#!/usr/bin/env python3
import traceback  # 🔍 引入模块


class Robot:
    """带上下文协议的机器人，演示 traceback 用法"""

    def __enter__(self):
        print("【enter】开机")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("【exit】关机")
        if exc_type:
            # 🔍 ① 直接把堆栈打印到控制台（像解释器一样）
            print("  控制台堆栈：")
            traceback.print_exc()  # 等价于 python 默认输出

            # 🔍 ② 拿到字符串，可写文件/发网络
            tb_str = traceback.format_exc()
            print("  日志文件内容→", repr(tb_str))  # 模拟写日志
        return False  # 继续向外抛

    def work(self, n):
        if n < 0:
            raise ValueError("参数不能为负")
        print(f"  工作中 {n} 小时")


# ---------------- 演示 1：异常被记录，然后继续抛 ----------------
def demo_continue_raise():
    try:
        with Robot() as bot:
            bot.work(-3)  # 会抛 ValueError
    except ValueError as e:
        print("外层捕获：", e)
    print("程序正常结束\n")


# ---------------- 演示 2：异常被吞，但堆栈已保存 ----------------
def demo_swallow():
    class RobotSwallow(Robot):
        def __exit__(self, exc_type, exc_val, exc_tb):
            if exc_type:
                # 🔍 同样用 traceback 记录，只是不往外抛
                tb_str = traceback.format_exc()
                print("  已记录堆栈，不向外抛：")
                print("  →", tb_str.splitlines()[-2])  # 只取异常行
                return True  # 吞掉
            return False

    with RobotSwallow() as bot:
        bot.work(-3)
    print("with 块后代码继续执行——异常已被吞\n")


# ---------------- 演示 3：不捕获，让异常冒到顶层 ----------------
def demo_no_catch():
    with Robot() as bot:
        bot.work(-3)
    print("这行永远看不到")


if __name__ == "__main__":
    demo_continue_raise()
    demo_swallow()
    # demo_no_catch()   # 打开后顶层打印 Traceback 并退出
